<template>
  <div class="yh-photoWall">
    <!-- 图片渲染包括删除区域 -->
    <div v-for="(img,index) in list" :key="img.id" class="yh-photoWall-img"
        :style="{height:height+'px',width:width+'px',marginRight:right+'px',marginBottom:bottom+'px'}"
        @mouseover ="showDelIcon(img.id)">
      <img :src="img.url" style="width:100%;height:100%" @mouseleave="delImgId=null" @dblclick="showPreviewImg(img.url,index)"/>
      <i class="el-icon-close yh-photoWall-x" v-if="delImgId === img.id || showAllDel"  @mouseenter ="showDelIcon(img.id)"  @mouseleave="delImgId=null" @click="delImg(img.id)"></i>
    </div>
    <!-- 上传图片区域 -->
    <div class="yh-photoWall-add"
        :style="{height:height+'px',width:width+'px',marginRight:right+'px',marginBottom:bottom+'px',lineHeight:height+'px',color:color,fontSize:size+'px',border:borderStyle, background:uploadBgc}"
        @click="clickFile"
    >
      <i v-if="showIcon" class="el-icon-plus"></i>
      <span v-else>{{uploadText}}</span>
    </div>
    <!-- <input type="file" class="yh-photoWall-file"> -->
    <!-- 预览图片区域 -->
    <div v-if="showFlag" class="showFlag" >
      <img :src="previewImgUrl"  class="previewImg" />
      <i class="el-icon-close yh-close-perview" @click="closeperview"></i>
      <i class="el-icon-zoom-in yh-big-perview" @click="perImgBig"></i>
      <i class="el-icon-zoom-out yh-samll-perview" @click="perImgSamll"></i>
      <i class="el-icon-arrow-left yh-left-perview" @click="leftPerImg"></i>
      <i class="el-icon-arrow-right yh-right-perview" @click="rightPerImg"></i>
      <div class="yh-current-box" :style="{width:list.length*30+'px'}" v-if="showCurrentBox">
        <span :class="['yh-current-perview',{'yh-current-perview-active':(i-1)===currentImg}]" v-for="i in list.length" :key="i" @click="jumpPreImg(i)"></span>
      </div>
    </div>
  </div>
</template>

<script>
/*  组件介绍：该组件为照片墙组件，包括上传图片，删除图片，图片预览功能。
 *  属性如下：
 *  imgList:必须值、初始的图片渲染列表，Array
 *  width:单元图片的宽度值默认为100px，height：单元图片的宽度值默认为100px；Number
 *  right：照片墙右侧距离默认值10px,bottom:照片墙下侧距离默认值10px;Number
 *  color：上传区域的文本及边框颜色，默认值#66b1ff，支持rgb\rgba\十六进制（3位或者6位）\hsl\hsla
 *  size：上传区域的文本字体大小，默认值20px;Number
 *  uploadText:上传区域的文本，默认值：点击上传。String
 *  borderStyle：上传区域的边框样式默认值直线，支持CSS一切边框样式。包括直线，曲线.... String[dashed \solid\dotted\double\groove\ridge\inset\outset]
 *  showIcon：上传区域是否显示图标，默认值不显示，如果设置则显示图标不显示文字。Boolean
 *  showAllDel：是否直接显示所有图片的删除按钮，默认值不显示，不显示的情况是由鼠标进入图片显示。Boolean
 *  base64：上传图片时返回给父组件的格式，默认是浏览器创建url，使用base64可以通过这个属性设置。Boolean
 *  showCurrentBox:是否展示当前图片位置。Boolean
 *  perviewMethods:触发预览图片的方式，默认为双击。可以选择click或者dblclick
 *  uploadBgc:修改上传图片区域的背景色,默认#fff,支持rgb\rgba\十六进制（3位或者6位）\hsl\hsla
 *  方法：
 *  getDelImgIdList(delImgIdList)传回去的delImgIdList是需要删除图片的id
 *  addImg(addImgList)传回去的addImgList是新增图片的信息，包括随机生成的Id与url。url参考base64属性
 */
function CheckIsColor(bgVal) {
  let type='';
  if(/^rgb\(/.test(bgVal)){
    //如果是rgb开头，200-249，250-255，0-199
    type = "^[rR][gG][Bb][\(]([\\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\\s]*,){2}[\\s]*(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)[\\s]*[\)]{1}$";
  }else if(/^rgba\(/.test(bgVal)){
    //如果是rgba开头，判断0-255:200-249，250-255，0-199 判断0-1：0 1 1.0 0.0-0.9
    type = "^[rR][gG][Bb][Aa][\(]([\\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?)[\\s]*,){3}[\\s]*(1|1.0|0|0.[0-9])[\\s]*[\)]{1}$";
  }else if(/^#/.test(bgVal)){
    //六位或者三位
    type = "^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$"
  }else if(/^hsl\(/.test(bgVal)){
    //判断0-360 判断0-100%(0可以没有百分号)
    type = "^[hH][Ss][Ll][\(]([\\s]*(2[0-9][0-9]|360｜3[0-5][0-9]|[01]?[0-9][0-9]?)[\\s]*,)([\\s]*((100|[0-9][0-9]?)%|0)[\\s]*,)([\\s]*((100|[0-9][0-9]?)%|0)[\\s]*)[\)]$";
  }else if(/^hsla\(/.test(bgVal)){
    type = "^[hH][Ss][Ll][Aa][\(]([\\s]*(2[0-9][0-9]|360｜3[0-5][0-9]|[01]?[0-9][0-9]?)[\\s]*,)([\\s]*((100|[0-9][0-9]?)%|0)[\\s]*,){2}([\\s]*(1|1.0|0|0.[0-9])[\\s]*)[\)]$";
  }
  let re = new RegExp(type);
  if (bgVal.match(re) == null){
    return false
  }else{
    return true
  }
}
export default {
  name:'photoWall',
  props:{
    imgList:{
      require:true,
      type:Array,
    },
    width:{
      type:Number,
      default:100,
    },
    height:{
      type:Number,
      default:100,
    },
    right:{
      type:Number,
      default:10,
    },
    bottom:{
      type:Number,
      default:10,
    },
    color:{
      default:function(){
        return '#66b1ff'
      },
      validator:function(value){
        return CheckIsColor(value)
      }
    },
    size:{
      default:20,
      type:Number
    },
    uploadText:{
      default:'点击上传',
      type:String
    },
    borderStyle:{
      default:function(){
        return 'solid'
      },
      type:String,
      validator:function(value){
        return ["dashed","solid","dotted","double","groove","ridge","inset","outset"].indexOf(value) !== -1
      }
    },
    showIcon:{
      default:false,
      type:Boolean
    },
    showAllDel:{
      default:false,
      type:Boolean
    },
    base64:{
      default:false,
      type:Boolean
    },
    showCurrentBox:{
      default:true,
      type:Boolean
    },
    uploadBgc:{
      default:function(){
        return '#fff'
      },
      validator:function(value){
        return CheckIsColor(value)
      }
    }
  },
  data(){
    return {
      delImgId:null,
      list:this.imgList,
      delImgIdList:[],
      addImgList:[],
      showFlag:false,
      previewImgUrl:null,
      currentImg:null,
      dbWidth:'',
      dbHeight:'',
    }
  },
  mounted(){
    this.getWindowHW()
    window.addEventListener('resize',this.getWindowHW)
  },
  destroyed(){
    window.removeEventListener('resize',this.getWindowHW())
  },
  methods:{
    // 获取浏览器宽高
    getWindowHW(){
      this.dbWidth=window.innerWidth;
      this.dbHeight=window.innerHeight;
    },
    // 让删除图标展示
    showDelIcon(imgId){
      this.delImgId=imgId
    },
    // 删除图片
    delImg(imgId){
      this.delImgIdList.push(imgId);
      this.$emit('getDelImgIdList',this.delImgIdList) //将删除图片的id给父组件
      this.list=this.list.filter(img=>img.id!=imgId)
    },
    // 上传图片
    clickFile(){
      let yhphotoBox = document.querySelector('.yh-photoWall')
      let uploadBtn = document.createElement('input')
      yhphotoBox.appendChild(uploadBtn)
      uploadBtn.setAttribute('type','file')
      uploadBtn.setAttribute('class','yh-photoWall-file')
      uploadBtn.click();
      let _that=this
      uploadBtn.onchange = function(){
        let that=this
        let imageList=["image/png","image/jpg","image/jpeg","image/gif"] //上传的图片类型白名单
        // console.log(that.files[0].type);
        if(!this.type||!imageList.some(item=>item===that.files[0].type)){
          return _that.$message.error('只支持png、jpeg、jpg、gif模式')
        }
        if(_that.base64 && that.files[0].size>128*1024){
          yhphotoBox.removeChild(uploadBtn)
          return _that.$message.warning('base64格式数据最大为128字节')
        }
        let url=''
        function uploadImg(url){
          _that.list.push({url,id:Math.random()*10000})
          _that.addImgList.push({url,id:Math.random()*10000})
          _that.$emit('addImg', _that.addImgList)
        }
        if(_that.base64){
          let reader =new FileReader();
          reader.readAsDataURL(that.files[0])
          reader.onload = function(){
            url=reader.result
            uploadImg(url)
            yhphotoBox.removeChild(uploadBtn)
          }
        }else{
          url=URL.createObjectURL(that.files[0]);
          uploadImg(url)
          yhphotoBox.removeChild(uploadBtn)
        }
      }
    },
    // 展示预览图片
    showPreviewImg(val,index){
      this.previewImgUrl=val;
      this.showFlag=true;
      this.currentImg=index;
    },
    // 关闭预览区域
    closeperview(){
      this.showFlag=false;
    },
    // 放大图片
    perImgBig(){
      // 放大预览图片
      const perImg=document.querySelector('.previewImg')
      const width=perImg.width
      const height=perImg.height
      const  nowWidth=width+50
      const computeRatio=nowWidth*height/width  //得到等比列的大小
      if(nowWidth>=(this.dbWidth-200)||computeRatio>=(this.dbHeight-200)){
        return
      }else{
        perImg.style.width=nowWidth+'px'
      }
    },
    // 缩小预览图片
    perImgSamll(){
      // 缩小图片
      const perImg=document.querySelector('.previewImg')
      const width=perImg.width
      const height=perImg.height
      if(width<=50||height<=50){
        return
      }else{
        const nowWidth=width-50
        perImg.style.width=nowWidth<=50?'50px':nowWidth+'px'
      }
    },
    // 像上一张
    leftPerImg(){
      document.querySelector('.previewImg').style.width='auto'
      this.currentImg=this.currentImg>0?--this.currentImg:this.list.length-1;
      this.previewImgUrl=this.list[this.currentImg].url;
    },
    // 预览下一张
    rightPerImg(){
      document.querySelector('.previewImg').style.width='auto'
      this.currentImg=this.currentImg<this.list.length-1?++this.currentImg:0;
      this.previewImgUrl=this.list[this.currentImg].url;
    },
    // 预览指定图片
    jumpPreImg(i){
      document.querySelector('.previewImg').style.width='auto'
      this.currentImg=i-1
      this.previewImgUrl=this.list[this.currentImg].url;
    }
  }
}
</script>

<style lang="less">
.yh-photoWall{
  .yh-photoWall-file{
    display: none;
  }
  .yh-photoWall-img{
    position: relative;
    display: inline-block;
    img{
      display: inline-block;
    }
    .yh-photoWall-x{
      position: absolute;
      top: 0;
      right: 0;
      transform: translate(50%,-50%);
      background-color: #333;
      color: #fff;
      border-radius: 50%;
    }
  }
  .yh-photoWall-add{
    text-align: center;
    display: inline-block;
    vertical-align: bottom;
    box-sizing: border-box;
  }
  .showFlag{
    width: 100%;
    height: 100%;
    background-color:rgba(0, 0, 0, 0.3);
    position: fixed;
    top: 0;
    left: 0;
    .previewImg{
      max-height: calc(100% - 200px);
      max-width: calc(100% - 200px);
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      z-index: 9999;
    }
    .yh-close-perview{
      position: absolute;
      top: 20px;
      right: 20px;
      font-size: 30px;
      color: #fff;
    }
    .yh-big-perview,.yh-samll-perview{
      position: absolute;
      bottom: 30px;
      color: #fff;
      font-size: 30px;
      left: 50%;
    }
    .yh-big-perview{
      transform: translate(calc(-50% - 55px));
    }
    .yh-samll-perview{
      transform: translate(calc(-50% + 55px));
    }
    .yh-left-perview,.yh-right-perview{
      position: absolute;
      top: 50%;
      color: #fff;
      background-color: rgb(92, 86, 86);
      border-radius: 50%;
      font-size: 30px;
      width: 50px;
      height: 50px;
      text-align: center;
      line-height: 50px;
    }
    .yh-left-perview{
      left: 50px;
    }
    .yh-right-perview{
      right: 50px;
    }
    .yh-current-perview{
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background-color: #666;
    }
    .yh-current-perview-active{
      background-color: #fff;
    }
    .yh-current-box{
      display: flex;
      position: absolute;
      bottom: 70px;
      left: 50%;
      justify-content: space-around;
      transform: translate(-50%);
    }
  }
}
</style>
